package com.woniuxy.session.service;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/**
 * @Author: linKe
 * @Date: 2022/1/6 11:36
 * @FileName: SomeService
 * @version: 1.0
 * @Description: 描述
 */
@Service
public class SomeService {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    /**
     * redissonClient 控制锁
     * stock
     */
    @Autowired
    RedissonClient redissonClient;

    public String some() {
        String str="";
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        if(!redisTemplate.hasKey("str")){
            System.out.println("查询数据库");
            str="测试";
            opsForValue.set("str",str);
        }else{
            System.out.println("查询缓存");
            str= (String) opsForValue.get("str");
        }
        return  str;
    }


    public Integer incr(){
        // 设置自增属性是否正常
        // CPU每次执行一条指令，汇编语言的语句和机器指令一一对应
        // 高级语言的一条语句对应多条指令
        // a = b+c mov ax,a  add ax,b  mov c,ax;
        // num++
        // Redis的指令是单线程执行，可以保证原子性： Redis的一条指令执行过程不会被打断
        redisTemplate.opsForValue().increment("num");
        return (Integer) redisTemplate.opsForValue().get("num");
    }

    /**
     * redissonClient 加锁
     * @return 结果
     */
    public Integer incrLock(){
        // 设置自增属性是否正常
        // CPU每次执行一条指令，汇编语言的语句和机器指令一一对应
        // 高级语言的一条语句对应多条指令
        // a = b+c mov ax,a  add ax,b  mov c,ax;
        // num++
        // Redis的指令是单线程执行，可以保证原子性： Redis的一条指令执行过程不会被打断

        // 加锁
        RLock myLock = redissonClient.getLock("myLock");
        myLock.lock();
        redisTemplate.opsForValue().increment("num");

        // 解锁
        myLock.unlock();
        return (Integer) redisTemplate.opsForValue().get("num");
    }
}

